package org.linuxsogood.boot.mysql;

import com.mysql.jdbc.Driver;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

/**
 * @author honway.liu
 * @date 2016/12/11 下午9:36
 * @email gm100861@gmail.com
 * @blog http://linuxsogood.org
 */
public class MyConnectionPool implements DataSource {

    //定义一个集合对象,用于存储连接
    //
    private static List<Connection> pool = new LinkedList<Connection>();

    private static final String url = "jdbc:mysql:///mydb";
    private static final String username="root";
    private static final String password="redhat";

    public MyConnectionPool() {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
            for (int i = 0; i < 5; i++) {
                Connection connection = DriverManager.getConnection(url, username, password);
                pool.add(connection);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Connection getConnection() throws SQLException {
        if (pool.size() == 0) {
            for (int i = 0; i < 3; i++) {
                Connection connection = DriverManager.getConnection(url, username, password);
                pool.add(connection);
            }
        }
        final Connection conn = pool.remove(0);
        //动态代理,返回生成的代理类.当用户调用close方法的时候,不是关闭连接,而是把连接放到我们定义的连接池里面
        return (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if ("close".equals(method.getName())) {
                    retConnection(conn);
                    return null;
                } else {
                    return method.invoke(conn, args);
                }
            }
        });
    }

    private void retConnection(Connection connection) throws SQLException {
        if (connection != null && !connection.isClosed()) {
            pool.add(connection);
        }
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}
